﻿# -*- coding:utf-8 -*-
import requests, time, re
import urllib
import pymysql

import json

from autotest.celery import app

import os
import logging
from django_redis import get_redis_connection
import datetime

PATH = lambda p: os.path.abspath(
    os.path.join(os.path.dirname(__file__), p)
)

global driver
# 日志
logger = logging.getLogger('apitest')


@app.task
def hello_world():
    logger.info("已运行")


@app.task
def apisauto_testcase():
    """
    全量单一接口执行
    """
    sql = "SELECT id,`apiname`,apiurl,apimethod,cookie_or_token,apiparamvalue,apiresult,`apistatus` from apitest_apis "
    coon = pymysql.connect(user='root', passwd='root123456!@#$%^', db='autotest', port=3306, host='127.0.0.1',
                           charset='utf8')
    cursor = coon.cursor()
    apitest_apis_allinfo = cursor.execute(sql)
    infos = cursor.fetchmany(apitest_apis_allinfo)
    logger.info("apisauto_testcase full task data %s", infos)
    for info in infos:
        case_list = []
        case_list.append(info)
        interfaceTest1(case_list)
    coon.commit()
    cursor.close()
    coon.close()


@app.task
def apitest_testcase():
    """
    全量流程接口执行
    """
    sql = "SELECT id,`apiname`,apiurl,apimethod,cookie_or_token,apiparamvalue,apiresult,`apistatus` from apitest_apistep where apitest_apistep.Apitest_id=2"
    coon = pymysql.connect(user='root', passwd='root123456!@#$%^', db='autotest', port=3306, host='127.0.0.1',
                           charset='utf8')
    cursor = coon.cursor()
    cuf_exec = cursor.execute(sql)
    infos = cursor.fetchmany(cuf_exec)
    logger.info("Data in apitest_apistep %s", infos)

    for info in infos:
        case_list = []
        case_list.append(info)
        #   CredentialId()
        interfaceTest(case_list)
    coon.commit()
    cursor.close()
    coon.close()


# 获取apitest_apis单一接口数据库的数据，按suiteid写到redis中
@app.task()
def apis_suiteid_in_redis():
    logger.info("start apitestapis_suiteid_in_redis get apis_suite and apis data")

    sql_apis_suite = "SELECT id from apitest_apissuite"
    sql_apis = "SELECT id,`apiname`,apiurl,apimethod,cookie_or_token,apiparamvalue,apiresult,`apistatus`,`Apissuite_id` from apitest_apis where Apissuite_id=%s"
    coon = pymysql.connect(user='root', passwd='root123456!@#$%^', db='autotest', port=3306, host='127.0.0.1',
                           charset='utf8')
    cursor = coon.cursor()
    apis_suiteid_curexec = cursor.execute(sql_apis_suite)
    suiteid_tuple = cursor.fetchmany(apis_suiteid_curexec)
    suiteid_list = list(suiteid_tuple)
    # 获取redis的conn对象
    redis_conn = get_redis_connection('default')

    for suiteid in suiteid_list:
        param = (suiteid)
        crurexec = cursor.execute(sql_apis, param)
        infos_tuple = cursor.fetchmany(crurexec)
        apis_info_list = list(infos_tuple)
        apis_info_len = len(apis_info_list)
        if apis_info_len > 0:
            # 设置key
            redis_key = "redis_apis_info_" + str(suiteid[0])
            redis_conn.set(redis_key, apis_info_list, 15 * 60)

    logger.info("end apitestapis_suiteid_in_redis get apis_suite and apis data")


# 获取apitest_apitestsuite流程接口数据库的数据，按suiteid写到redis中
@app.task()
def apitest_suiteid_in_redis():
    logger.info("start apitest_suiteid_in_redis get apitest_suite and apitest data")

    sql_apitest_suite = "SELECT id from apitest_apitestsuite"
    sql_apitest = "SELECT id from apitest_apitest where Apitestsuite_id=%s"
    sql_apistep = "SELECT id,`apiname`,apiurl,apimethod,cookie_or_token,apiparamvalue,apiresult,`apistatus` from apitest_apistep where Apitest_id=%s"
    coon = pymysql.connect(user='root', passwd='root123456!@#$%^', db='autotest', port=3306, host='127.0.0.1',
                           charset='utf8')
    cursor = coon.cursor()
    apitest_suiteid_curexec = cursor.execute(sql_apitest_suite)
    suiteid_tuple = cursor.fetchmany(apitest_suiteid_curexec)
    suiteid_list = list(suiteid_tuple)
    # 获取redis的conn对象
    redis_conn = get_redis_connection('default')

    for suiteid in suiteid_list:
        param = (suiteid)
        crurexec = cursor.execute(sql_apitest, param)
        infos_tuple = cursor.fetchmany(crurexec)
        apitestid_list = list(infos_tuple)
        apitestid_list_len = len(apitestid_list)
        if apitestid_list_len > 0:
            for apitestid in apitestid_list:
                param = (apitestid)
                crurexec = cursor.execute(sql_apistep, param)
                apistep_infos_tuple = cursor.fetchmany(crurexec)
                apistep_infos_list = list(apistep_infos_tuple)
                apitest_infos_list_len = len(apitestid_list)
                if apitest_infos_list_len > 0:
                    # 设置key
                    redis_key = "redis_apitest_info_" + str(suiteid[0]) + "_" + str(apitestid[0])
                    redis_conn.set(redis_key, apistep_infos_list, 15 * 60)

    logger.info("end apitest_suiteid_in_redis get apitest_suite and apitest data")


# 获取apitest_apitest流程接口数据库的数据，按apitestid写到redis中
@app.task()
def apitest_id_in_redis():
    logger.info("start apitest_suiteid_in_redis get apitest_suite and apitest data")

    sql_apitest = "SELECT id from apitest_apitest"
    sql_apistep = "SELECT id,`apiname`,apiurl,apimethod,cookie_or_token,apiparamvalue,apiresult,`apistatus` from apitest_apistep where Apitest_id=%s"
    coon = pymysql.connect(user='root', passwd='root123456!@#$%^', db='autotest', port=3306, host='127.0.0.1',
                           charset='utf8')
    cursor = coon.cursor()
    apitest_id_curexec = cursor.execute(sql_apitest)
    suiteid_tuple = cursor.fetchmany(apitest_id_curexec)
    suiteid_list = list(suiteid_tuple)
    # 获取redis的conn对象
    redis_conn = get_redis_connection('default')

    for suiteid in suiteid_list:
        param = (suiteid)
        crurexec = cursor.execute(sql_apitest, param)
        infos_tuple = cursor.fetchmany(crurexec)
        apitestid_list = list(infos_tuple)
        apitestid_list_len = len(apitestid_list)
        if apitestid_list_len > 0:
            for apitestid in apitestid_list:
                param = (apitestid)
                crurexec = cursor.execute(sql_apistep, param)
                apistep_infos_tuple = cursor.fetchmany(crurexec)
                apistep_infos_list = list(apistep_infos_tuple)
                apitest_infos_list_len = len(apitestid_list)
                if apitest_infos_list_len > 0:
                    # 设置key
                    redis_key = "redis_apitest_info_" + str(suiteid[0]) + "_" + str(apitestid[0])
                    redis_conn.set(redis_key, apistep_infos_list, 15 * 60)

    logger.info("end apitest_suiteid_in_redis get apitest_suite and apitest data")


# 执行定时任务中任务方法，新增加一个@app.task()，需要在task_map中添加
def periodictask_task_method(periodictask_task):
    # 任务方法
    task_map = {'apisauto_testcase': 'apisauto_testcase()',
                'apitest_testcase': 'apitest_testcase()',
                'apis_suiteid_in_redis': 'apis_suiteid_in_redis()',
                'apitest_suiteid_in_redis': 'apitest_suiteid_in_redis()',
                }
    t1 = datetime.datetime.now()
    flag = 'failed'
    for key in task_map.keys():
        if key in periodictask_task:
            flag = 'passed'
            eval(task_map[key])
    t2 = datetime.datetime.now()
    return {'flag': flag,
            'execuTime': str(t2 - t1)}


# 根据apis_suite数据库id（suiteid），手工执行单一接口，批量执行redis或apitest_apis数据库中（一条或多条）数据
def manual_apissuite_testcase(apis_suiteid):
    t1 = datetime.datetime.now()
    retResult = {"caseCount": 0, "passedNum": 0, "failedNum": 0, "caseMsg": [], "totalExecuTime": 0.0}
    caseInfo = {"execuTime": 0, "caseId": 0, "caseName": "", "caseResult": ""}

    # 连接redis
    redis_conn = get_redis_connection('default')
    apitestapis_info_str = redis_conn.get("redis_apis_info_" + apis_suiteid)
    logger.info("manual_apissuite_testcase get apitest_apis redis all data %s", apitestapis_info_str)
    # redis缓存中无数据或无key，从apitest_apis数据库中获取数据，再设置redis缓存数据
    if apitestapis_info_str == '' or apitestapis_info_str == None:
        apitestapis_info_tuple = get_apitestapis_info(apis_suiteid)  # 根据suiteid获取数据库中单一接口数据
        apis_info_tuple2list = list(apitestapis_info_tuple)  # tuple数据转成[()]列表元组
        apis_info_tuple2list_len = len(apis_info_tuple2list)
        if apis_info_tuple2list_len == 0:
            retResult['caseMsg'].append({'caseResult': 'no case'})
            retResult['caseCount'] = len(retResult['caseMsg'])
            return retResult
        # 设置key
        redis_key = "redis_apis_info_" + apis_suiteid
        redis_conn.set(redis_key, apis_info_tuple2list, 15 * 60)  # 写入redis
    else:
        apis_info_tuple2list = eval(apitestapis_info_str)  # str数据转成[()]列表元组

    for apis_allinfo_tuple in apis_info_tuple2list:
        case_list = list(apis_allinfo_tuple)
        t_apis_1 = datetime.datetime.now()
        apisResult = interfaceTest1(case_list)  # 调单一接口方法
        t_apis_2 = datetime.datetime.now()

        caseInfo['execuTime'] = str(t_apis_2 - t_apis_1)
        caseInfo['caseId'] = case_list[0]
        caseInfo['caseName'] = case_list[1]
        caseInfo['caseResult'] = apisResult['flag']

        retResult['caseMsg'].append(caseInfo.copy())
        if apisResult.get('flag') == 'pass':
            retResult['passedNum'] += 1
        elif apisResult.get('flag') == 'fail':
            retResult['failedNum'] += 1
        retResult['caseCount'] = len(retResult['caseMsg'])
    t2 = datetime.datetime.now()
    retResult['totalExecuTime'] = str(t2 - t1)
    return retResult


# 根据suiteid获取单一接口apitest_apis数据库的数据
def get_apitestapis_info(suiteid):
    sql = "SELECT id,`apiname`,apiurl,apimethod,cookie_or_token,apiparamvalue,apiresult,`apistatus`,`Apissuite_id` from apitest_apis where Apissuite_id=%s"
    param = (suiteid)
    coon = pymysql.connect(user='root', passwd='root123456!@#$%^', db='autotest', port=3306, host='127.0.0.1',
                           charset='utf8')
    cursor = coon.cursor()
    apis_info_curexec = cursor.execute(sql, param)
    infos_tuple = cursor.fetchmany(apis_info_curexec)
    logger.info("get_apissuite_allinfo database all data %s", infos_tuple)
    return infos_tuple


# 根据apisid获取单一接口apitest_apis数据库的数据
def get_apitestapis_id_info(apis_id):
    sql = "SELECT id,`apiname`,apiurl,apimethod,cookie_or_token,apiparamvalue,apiresult,`apistatus`,`Apissuite_id` from apitest_apis where id=%s"
    param = (apis_id)
    coon = pymysql.connect(user='root', passwd='root123456!@#$%^', db='autotest', port=3306, host='127.0.0.1',
                           charset='utf8')
    cursor = coon.cursor()
    apis_info_curexec = cursor.execute(sql, param)
    infos_tuple = cursor.fetchmany(apis_info_curexec)
    logger.info("get_apissuite_allinfo database all data %s", infos_tuple)
    return infos_tuple


# 根据apisid，手工执行单一接口，执行apitest_apis数据库中（一条）数据
def manual_apis_testcase(apis_id):
    retResult = {}
    t1 = datetime.datetime.now()
    apitestapis_info_tuple = get_apitestapis_id_info(apis_id)  # 根据suiteid获取数据库中单一接口数据
    apis_info_tuple2list = list(apitestapis_info_tuple)  # tuple数据转成[()]列表元组
    logger.info("manual_apis_testcase get_apitestapis_allinfo redis all data %s", apis_info_tuple2list)

    for allinfo_tuple in apis_info_tuple2list:
        case_list = list(allinfo_tuple)
        retResult = interfaceTest1(case_list)
    t2 = datetime.datetime.now()
    retResult['execuTime'] = str(t2 - t1)
    return retResult


# 根据apitestsuite_id获取apitest数据库中id
def get_apitestid(suiteid):
    apitest_sql = "SELECT id FROM apitest_apitest WHERE Apitestsuite_id=%s"
    param = (suiteid)
    coon = pymysql.connect(user='root', passwd='root123456!@#$%^', db='autotest', port=3306, host='127.0.0.1',
                           charset='utf8')
    cursor = coon.cursor()
    apitest_id_curexec = cursor.execute(apitest_sql, param)
    id_tuple = cursor.fetchmany(apitest_id_curexec)
    logger.info("get_apitestid database id data %s", id_tuple)
    return id_tuple


# 根据apitest_id获取apistep数据库中用例数据
def get_apistep_case(apitest_id):
    apistep_sql = "SELECT id,`apiname`,apiurl,apimethod,cookie_or_token,apiparamvalue,apiresult,`apistatus`,`Apitest_id` from apitest_apistep where Apitest_id=%s"
    param = (apitest_id)
    coon = pymysql.connect(user='root', passwd='root123456!@#$%^', db='autotest', port=3306, host='127.0.0.1',
                           charset='utf8')
    cursor = coon.cursor()
    apistep_info_curexec = cursor.execute(apistep_sql, param)
    infos_tuple = cursor.fetchmany(apistep_info_curexec)
    logger.info("get_apistep_case database data %s", infos_tuple)
    return infos_tuple


# 手工执行流程接口，批量执行apitest_suite数据库中数据
def manual_apitestsuite_testcase(apitest_suiteid):
    t1 = datetime.datetime.now()
    retResult = {"caseCount": 0, "passedNum": 0, "failedNum": 0, "caseMsg": [], "totalExecuTime": 0.0}
    caseInfo = {"execuTime": 0, "caseId": 0, "caseName": "", "caseResult": ""}

    # 连接redis
    redis_conn = get_redis_connection('default')
    apitest_id_tuple = get_apitestid(apitest_suiteid)  # 根据suiteid获取数据库中apitest_id数据
    for apitest_id in apitest_id_tuple:
        apitestId = str(apitest_id[0])
        redis_key = "redis_apitest_info_" + apitest_suiteid + "_" + apitestId
        apitest_info_str = redis_conn.get(redis_key)
        logger.info("manual_apitestsuite_testcase get apitest_suite redis all data %s", apitest_info_str)

        # redis缓存中无数据或无key，从apitest_apis数据库中获取数据，再设置redis缓存数据
        if apitest_info_str == '' or apitest_info_str == None:
            apitest_case_tuple = get_apistep_case(apitestId)  # 根据apitest_id获取apistep数据库中用例数据
            apitest_info_tuple2list = list(apitest_case_tuple)  # tuple数据转成[()]列表元组
            apis_info_tuple2list_len = len(apitest_info_tuple2list)
            if apis_info_tuple2list_len == 0:
                retResult['caseMsg'].append({'caseResult': 'no case'})
                retResult['caseCount'] = len(retResult['caseMsg'])
                continue
            # 设置key
            redis_conn.set(redis_key, apitest_info_tuple2list, 15 * 60)  # 写入redis
        else:
            apitest_info_tuple2list = eval(apitest_info_str)  # str数据转成[()]列表元组

        for apitest_info_tuple in apitest_info_tuple2list:
            case_list = list(apitest_info_tuple)
            t_apitest_1 = datetime.datetime.now()
            apitestResult = interfaceTest(case_list, apitestId)  # 调单一接口方法
            t_apitest_2 = datetime.datetime.now()

            caseInfo['execuTime'] = str(t_apitest_2 - t_apitest_1)
            caseInfo['caseId'] = case_list[0]
            caseInfo['caseName'] = case_list[1]
            caseInfo['caseResult'] = apitestResult['flag']

            retResult['caseMsg'].append(caseInfo.copy())
            if apitestResult.get('flag') == 'pass':
                retResult['passedNum'] += 1
            elif apitestResult.get('flag') == 'fail':
                retResult['failedNum'] += 1
            retResult['caseCount'] = len(retResult['caseMsg'])
        t2 = datetime.datetime.now()
        retResult['totalExecuTime'] = str(t2 - t1)
    return retResult


# 手工执行流程接口manual_req_processInterface（执行一个接口）
def manual_apitest_testcase(apitest_id):
    t1 = datetime.datetime.now()
    retResult = {"caseCount": 0, "passedNum": 0, "failedNum": 0, "caseMsg": [], "totalExecuTime": 0.0}
    caseInfo = {"execuTime": 0, "caseId": 0, "caseName": "", "caseResult": ""}

    # 连接redis
    redis_conn = get_redis_connection('default')

    redis_key = "redis_apitest_info_" + apitest_id
    apitest_info_str = redis_conn.get(redis_key)
    logger.info("manual_apitest_testcase get apitest redis all data %s", apitest_info_str)

    # redis缓存中无数据或无key，从apitest_apis数据库中获取数据，再设置redis缓存数据
    if apitest_info_str == '' or apitest_info_str == None:
        apitest_case_tuple = get_apistep_case(apitest_id)  # 根据apitest_id获取apistep数据库中用例数据
        apitest_info_tuple2list = list(apitest_case_tuple)  # tuple数据转成[()]列表元组
        apis_info_tuple2list_len = len(apitest_info_tuple2list)
        if apis_info_tuple2list_len == 0:
            retResult['caseMsg'].append({'caseResult': 'no case'})
            retResult['caseCount'] = len(retResult['caseMsg'])
            return retResult
        # 设置key
        redis_conn.set(redis_key, apitest_info_tuple2list, 15 * 60)  # 写入redis
    else:
        apitest_info_tuple2list = eval(apitest_info_str)  # str数据转成[()]列表元组

    # 发送请求，汇总请求结果
    for apitest_info_tuple in apitest_info_tuple2list:
        case_list = list(apitest_info_tuple)
        t_apitest_1 = datetime.datetime.now()
        apitestResult = interfaceTest(case_list, apitest_id)  # 调单一接口方法
        t_apitest_2 = datetime.datetime.now()

        caseInfo['execuTime'] = str(t_apitest_2 - t_apitest_1)
        caseInfo['caseId'] = case_list[0]
        caseInfo['caseName'] = case_list[1]
        caseInfo['caseResult'] = apitestResult['flag']

        retResult['caseMsg'].append(caseInfo.copy())
        if apitestResult.get('flag') == 'pass':
            retResult['passedNum'] += 1
        elif apitestResult.get('flag') == 'fail':
            retResult['failedNum'] += 1
        retResult['caseCount'] = len(retResult['caseMsg'])

    t2 = datetime.datetime.now()
    retResult['totalExecuTime'] = str(t2 - t1)
    return retResult


# 手工执行流程接口间依赖
def manual_apitest_testcase_dependent(apitest_id):
    t1 = datetime.datetime.now()
    retResult = {"caseCount": 0, "passedNum": 0, "failedNum": 0, "caseMsg": [], "totalExecuTime": 0.0}
    caseInfo = {"execuTime": 0, "caseId": 0, "caseName": "", "caseResult": ""}
    # 连接redis
    redis_conn = get_redis_connection('default')

    # 1、查redis或库得到step中有几步
    redis_key = "redis_apitest_info_" + apitest_id
    apitest_info_str = redis_conn.get(redis_key)
    logger.info("manual_apitest_testcase_dependent get apitest redis all data %s", apitest_info_str)
    # redis缓存中无数据或无key，从apitest_apis数据库中获取数据，再设置redis缓存数据
    if apitest_info_str == '' or apitest_info_str == None:
        apitest_case_tuple = get_apistep_case(apitest_id)  # 根据apitest_id获取apistep数据库中用例数据
        apitest_info_tuple2list = list(apitest_case_tuple)  # tuple数据转成[()]列表元组
        apis_info_tuple2list_len = len(apitest_info_tuple2list)
        if apis_info_tuple2list_len == 0:
            retResult['caseMsg'].append({'caseResult': 'no case'})
            retResult['caseCount'] = len(retResult['caseMsg'])
            return retResult
        # 设置key
        redis_conn.set(redis_key, apitest_info_tuple2list, 15 * 60)  # 写入redis
    else:
        apitest_info_tuple2list = eval(apitest_info_str)  # str数据转成[()]列表元组

    # 计数
    count = 1
    # 2、发送请求，汇总请求结果
    for apitest_info_tuple in apitest_info_tuple2list:
        case_list = list(apitest_info_tuple)
        t_apitest_1 = datetime.datetime.now()

        # 构造入参（修改参数）
        if count > 1:
            result_str = apitestResult['content']
            inParam = case_list[5]
            matchFields_dict = two_dict_key(json.loads(result_str), json.loads(inParam))
            case_list[5] = two_curly_braces(matchFields_dict, json.loads(inParam))

        apitestResult = interfaceTest(case_list, apitest_id)  # 调单一接口方法
        count += 1
        t_apitest_2 = datetime.datetime.now()

        caseInfo['execuTime'] = str(t_apitest_2 - t_apitest_1)
        caseInfo['caseId'] = case_list[0]
        caseInfo['caseName'] = case_list[1]
        caseInfo['caseResult'] = apitestResult['flag']

        retResult['caseMsg'].append(caseInfo.copy())
        if apitestResult.get('flag') == 'pass':
            retResult['passedNum'] += 1
        elif apitestResult.get('flag') == 'fail':
            retResult['failedNum'] += 1
        retResult['caseCount'] = len(retResult['caseMsg'])

    t2 = datetime.datetime.now()
    return retResult


# 单一接口，任务apisauto_testcase，手工执行manual_req_singleInterface
def interfaceTest1(case_list):
    logger.info("interfaceTest1 case params %s", case_list)
    global results
    res_flags = []
    request_urls = []
    responses = []
    strinfo = re.compile('{seturl}')
    res = {'flag': None,
           'describe': None,
           'content': None}

    try:
        case_id = case_list[0]
        interface_name = case_list[1]
        url = case_list[2]
        method = case_list[3]
        cookie_or_token = case_list[4]
        param = case_list[5]
        res_check = case_list[6]
    except Exception as e:
        return {'flag': 'fail',
                'describe': '不通过',
                'content': '测试用例格式不正确！%s' % e}

    if "{seturl}" in url:
        url = strinfo.sub(str(seturl('seturl')), url)
        url = 'http://' + url

    regex = "(http|https):\/\/([\w.]+\/?)\S*"
    regular = re.compile(regex)
    if '/' == url[0]:
        url_head_tup = regular.findall(url)
    else:
        url_head_tup = regular.findall(url)[0]

    if 0 == len(url_head_tup) and '/' == url[0]:
        new_url = 'http://' + str(seturl('seturl')) + url
    elif 'http' == url_head_tup[0] or 'https' == url_head_tup[0] and '/' != url[0]:
        new_url = url
    else:
        url = strinfo.sub(str(seturl('seturl')), url)  # 替换url中域名
        new_url = 'http://' + url
        request_urls.append(new_url)

    if method.upper() == 'GET':
        headers = {'cookie': cookie_or_token, 'Content-Type': 'application/json'}
        if "=" in urlParam(param):
            data = None
            logger.info("GET Request parameters case_id: %s, new_url: %s, urlParam: %s", case_id,
                        new_url.encode('utf-8'), urlParam(param).encode('utf-8'))
            results = requests.get(new_url + '?' + urlParam(param), data, headers=headers).text
            logger.info("GET Response Result %s", results.encode('utf-8'))
            responses.append(results)
            res = readRes(results, res_check)
            logger.info("readResponse GET %s", res)
            if 'pass' == res.get('flag'):
                res_flags.append('pass')
                caseWriteResult1(case_id, results, '1')
            else:
                res_flags.append('fail')
                caseWriteResult1(case_id, results, '0')
                writeBug(case_id, interface_name, new_url, results, res_check)
        else:
            logger.info("request  is get %s, body is %s", new_url, urlParam(param))
            data = None
            req = urllib.request.Request(url=new_url, data=data, headers=headers, method="GET")
            try:
                results = urllib.request.urlopen(req).read().decode("utf-8")
                logger.info("get response result %s", results)
            except Exception as e:
                logger.exception("get request exception %s", e)
                return caseWriteResult1(case_id, results, '0')
            res = readRes(results, res_check)
            logger.info("readResponse GET %s", res)
            if 'pass' == res.get('flag'):
                res_flags.append('pass')
                caseWriteResult1(case_id, results, '1')
            else:
                res_flags.append('fail')
                caseWriteResult1(case_id, results, '0')
                writeBug(case_id, interface_name, new_url, results, res_check)
    if method.upper() == "POST":
        headers = {'cookie': cookie_or_token, 'Content-Type': 'application/json'}
        logger.info("request is post %s, body is %s", new_url, headers, urlParam(param))
        param = eval(param)
        data = json.dumps(param).encode('utf-8')
        try:
            results = requests.post(url=new_url, data=data, headers=headers).content.decode('utf-8')
            logger.info("Post Response Result %s", results)
        except Exception as e:
            logger.exception("Post request Exception %s", e)
            return caseWriteResult1(case_id, results, '0')
        res = readRes(results, res_check)
        logger.info("readResponse Post %s", res)
        if 'pass' == res.get('flag'):
            res_flags.append('pass')
            caseWriteResult1(case_id, results, '1')
        else:
            res_flags.append('fail')
            caseWriteResult1(case_id, results, '0')
            writeBug(case_id, interface_name, new_url, results, res_check)
    if method.upper() == 'PUT':
        HOSTNAME = url_head_tup[1]
        headers = {'Host': HOSTNAME, 'cookie': cookie_or_token, 'Connection': 'keep-alive', 'CredentialId': id,
                   'Content-Type': 'application/json'}
        body_data = param
        results = requests.put(url=url, data=body_data, headers=headers)
        results = str(results, 'utf-8')
        logger.info("Put Response Result %s", results)
        responses.append(results)
        res = readRes(results, res_check)
        if 'pass' == res:
            #         writeResult(case_id,'pass')
            res_flags.append('pass')
        else:
            res_flags.append('fail')
            #     writeResult(case_id,'fail')
            writeBug(case_id, interface_name, new_url, results, res_check)
    if method.upper() == "PATCH":
        headers = {'cookie': cookie_or_token, 'Content-Type': 'application/json'}
        data = None
        results = requests.patch(new_url + '?' + urlParam(param), data, headers=headers).text
        results = str(results, 'utf-8')
        responses.append(results)
        res = readRes(results, res_check)
        if 'pass' == res:
            #     writeResult(case_id,'pass')
            res_flags.append('pass')
        else:
            res_flags.append('fail')
            #      writeResult(case_id,'fail')
            writeBug(case_id, interface_name, new_url, results, res_check)
    return res


seq1_sub = {}
result_dict = {}


# 字典中取相同的key并得到value
def two_dict_key(seq1, seq2):
    global seq1_sub
    global result_dict
    for s1 in seq1.keys():
        if isinstance(seq1[s1], dict):
            seq1_sub = seq1[s1]
            two_dict_key(seq1_sub, seq2)
        if isinstance(seq1[s1], list):
            for i in range(len(seq1[s1])):
                seq1_sub = seq1[s1][i]
                two_dict_key(seq1_sub, seq2)

        result_key = seq1.keys() & seq2.keys()
        result_tmp = seq1_sub

    for key in result_key:
        result_dict[key] = result_tmp[key]

    if len(result_key) > 0:
        # print(result_key, result_dict)
        return result_dict
    return result_dict


# 替换两个大括号中的字段
def two_curly_braces(matchFieldDict, targetDict):
    if matchFieldDict != None:
        targetDict_str = str(targetDict)
        for matchField in matchFieldDict.keys():
            if matchField in str(targetDict.keys()).replace("[", "").replace("]", ""):
                targetDict_str = json.dumps(
                    eval(targetDict_str.replace("{{" + matchField + "}}", str(matchFieldDict[matchField]))))
    return targetDict_str


def urlParam(param):
    param1 = param.replace('&quot;', '"')
    return param1


def CredentialId():
    global id
    url = 'http://' + 'api.test.com.cn' + '/api/Security/Authentication/Signin/web'
    body_data = json.dumps({"Identity": 'test', "Password": 'test'})
    headers = {'Connection': 'keep-alive', 'Content-Type': 'application/json'}
    response = requests.post(url=url, data=body_data, headers=headers)
    data = response.text
    regx = '.*"CredentialId":"(.*)","Scene"'
    pm = re.search(regx, data)
    id = pm.group(1)


def seturl(set):
    global setvalue
    sql = "SELECT `setname`,`setvalue` from set_set"
    coon = pymysql.connect(user='root', passwd='root123456!@#$%^', db='autotest', port=3306, host='127.0.0.1',
                           charset='utf8')
    cursor = coon.cursor()
    curexec = cursor.execute(sql)
    info = cursor.fetchmany(curexec)
    logger.info("Data in set_set %s", info)
    coon.commit()
    cursor.close()
    coon.close()
    if info[0][0] == set:
        setvalue = info[0][1]
        logger.info("setvalue %s", setvalue)
    return setvalue


def writeBug(bug_id, interface_name, request, response, res_check):
    interface_name = interface_name.encode('utf-8')
    res_check = res_check.encode('utf-8')
    request = request.encode('utf-8')
    now = time.strftime("%Y-%m-%d %H:%M:%S")
    bugname = str(bug_id) + '_' + interface_name.decode() + '_出错了'
    bugdetail = '[请求数据]<br />' + request.decode() + '<br/>' + '[预期结果]<br/>' + res_check.decode() + '<br/>' + '<br/>' + '[响应数据]<br />' + '<br/>' + response.decode()
    logger.info("writeBug bugdetail %s", bugdetail)
    sql = "INSERT INTO `bug_bug` (" \
          "`bugname`,`bugdetail`,`bugstatus`,`buglevel`, `bugcreater`, `bugassign`,`created_time`,`Product_id`)  " \
          "VALUES ('%s','%s','激活','3','tester', 'tester', '%s', '2');" % (
              bugname, pymysql.escape_string(bugdetail), now)
    coon = pymysql.connect(user='root', passwd='root123456!@#$%^', db='autotest', port=3306, host='127.0.0.1',
                           charset='utf8')
    cursor = coon.cursor()
    cursor.execute(sql)
    coon.commit()
    cursor.close()
    coon.close()


# 读取响应结果，手工执行manual_req_processInterface
def readRes(res, res_check):
    # res = res.decode().replace('":"', "=").replace('":', "=")
    res_check = res_check.split(';')
    for s in res_check:
        if s in res:
            break
        else:
            return {'flag': 'fail',
                    'describe': '错误，返回参数和预期结果不一致 ' + s,
                    'content': res}
    return {'flag': 'pass',
            'describe': '通过',
            'content': res}


def interfaceTest(case_list, apitestId):
    logger.info("interfaceTest case params %s", case_list)
    results = ""
    res_flags = []
    request_urls = []
    responses = []
    strinfo = re.compile('{seturl}')
    strinfo2 = re.compile('{TaskId}')
    tasknoinfo = re.compile('{taskno}')
    #   schemainfo = re.compile('{schema}')
    res = {'flag': None,
           'describe': None,
           'content': None}

    try:
        case_id = case_list[0]
        interface_name = case_list[1]
        url = case_list[2]
        method = case_list[3]
        cookie_or_token = case_list[4]
        param = case_list[5]
        res_check = case_list[6]
    except Exception as e:
        logger.error("测试用例格式不正确 %s", e)
        return '测试用例格式不正确！%s' % e

    if "{seturl}" in url:
        url = strinfo.sub(str(seturl('seturl')), url)
        url = 'http://' + url

    regex = "(http|https):\/\/([\w.]+\/?)\S*"
    regular = re.compile(regex)
    if '/' == url[0]:
        url_head_tup = regular.findall(url)
    else:
        url_head_tup = regular.findall(url)[0]

    if 0 == len(url_head_tup) and '/' == url[0]:
        new_url = 'http://' + str(seturl('seturl')) + url
    elif 'http' == url_head_tup[0] or 'https' == url_head_tup[0] and '/' != url[0]:
        new_url = url
    else:
        #  url = schemainfo.sub(mod_config.getConfig('project', "schema"),url)
        #  url = strinfo2.sub(TaskId,url)
        param = strinfo.sub(TaskId, param)
        param = tasknoinfo.sub(taskno, param)
        url = strinfo.sub(str(seturl('seturl')), url)  # 替换url中域名
        new_url = 'http://' + url
        request_urls.append(new_url)

    if method.upper() == 'GET':
        headers = {'cookie': cookie_or_token, 'Content-Type': 'application/json'}
        if "=" in urlParam(param):
            data = None
            logger.info("GET Request parameters case_id: %s, new_url: %s, urlParam: %s", case_id,
                        new_url.encode('utf-8'), urlParam(param).encode('utf-8'))
            results = requests.get(new_url + '?' + urlParam(param), data, headers=headers).text
            logger.info("GET Response Result %s", results.encode('utf-8'))
            responses.append(results)
            res = readRes(results, res_check)
            logger.info("readResponse GET %s", res)
            if 'pass' == res.get('flag'):
                res_flags.append('pass')
                writeResult(case_id, results, '1')
                caseWriteResult(case_id, '1')
            else:
                res_flags.append('fail')
                writeResult(case_id, results, '0')  # apitest_apistep，步骤中写结果
                caseWriteResult(case_id, '0')  # apitest_apitest，用例中写结果
                writeBug(case_id, interface_name, new_url, results, res_check)  # bug_bug 记录Bug
        else:
            logger.info("request is get %s, body is %s", new_url, urlParam(param))
            data = None
            try:
                results = requests.get(new_url, data, headers=headers).text
                logger.info("get Response Result %s", results)
            except Exception as e:
                logger.exception("get request exception %s", e)
                return caseWriteResult(case_id, '0')
            res = readRes(results, res_check)
            logger.info("readResponse get %s", res)
            if 'pass' == res.get('flag'):
                res_flags.append('pass')
                writeResult(case_id, results, '1')  # apitest_apistep，步骤中写结果
                caseWriteResult(apitestId, '1')  # apitest_apitest，用例中写结果
            else:
                res_flags.append('fail')
                writeResult(case_id, results, '0')  # apitest_apistep，步骤中写结果
                caseWriteResult(apitestId, '0')  # apitest_apitest，用例中写结果
                writeBug(case_id, interface_name, new_url, results, res_check)  # bug_bug 记录Bug
    if method.upper() == "POST":
        headers = {'cookie': cookie_or_token, 'Content-Type': 'application/json;charset=utf-8'}
        logger.info("request is post %s, body is %s", new_url, headers, urlParam(param))
        param = eval(param)
        data = json.dumps(param).encode('utf-8')
        try:
            results = requests.post(url=new_url, data=data, headers=headers).content.decode('utf-8')
            logger.info("post Response Result %s", results)
        except Exception as e:
            logger.exception("post exception %s", e)
            writeResult(case_id, results, '0')
            caseWriteResult(case_id, '0')
            return writeBug(case_id, interface_name, new_url, results, res_check)
        res = readRes(results, res_check)
        logger.info("readResponse get %s", res)
        if 'pass' == res.get('flag'):
            res_flags.append('pass')
            writeResult(case_id, results, '1')
            caseWriteResult(case_id, '1')
        else:
            res_flags.append('fail')
            writeResult(case_id, results, '0')  # apitest_apistep，步骤中写结果
            caseWriteResult(case_id, '0')  # apitest_apitest，流程用例中写结果
            writeBug(case_id, interface_name, new_url, results, res_check)  # bug_bug，记录bug
        try:
            TaskId(results)
        except Exception as e:
            logger.exception("post exception %s", e)
    if method.upper() == 'PUT':
        HOSTNAME = url_head_tup[1]
        headers = {'Host': HOSTNAME, 'cookie': cookie_or_token, 'Connection': 'keep-alive', 'CredentialId': id,
                   'Content-Type': 'application/json'}
        body_data = param
        results = requests.put(url=url, data=body_data, headers=headers)
        results = str(results, 'utf-8')
        logger.info("PUT Response Result %s", results)
        responses.append(results)
        res = readRes(results, res_check)
        logger.info("readResponse PUT %s", res)
        if 'pass' == res:
            writeResult(case_id, 'pass')
            res_flags.append('pass')
        else:
            res_flags.append('fail')
            writeResult(case_id, 'fail')
            writeBug(case_id, interface_name, new_url, results, res_check)
        try:
            preOrderSN(results)
        except Exception as e:
            logger.exception("PUT Exception %s", e)
    if method.upper() == "PATCH":
        headers = {'cookie': cookie_or_token, 'Content-Type': 'application/json'}
        data = None
        logger.info("PATCH Request parameters case_id: %s, new_url: %s, urlParam: %s", case_id,
                    new_url.encode('utf-8'), urlParam(param).encode('utf-8'))
        results = requests.patch(new_url + '?' + urlParam(param), data, headers=headers).text
        results = str(results, 'utf-8')
        logger.info("PATCH Response Result %s", results)
        responses.append(results)
        res = readRes(results, res_check)
        logger.info("readResponse PATCH %s", res)
        if 'pass' == res:
            writeResult(case_id, 'pass')
            res_flags.append('pass')
        else:
            res_flags.append('fail')
            writeResult(case_id, 'fail')
            writeBug(case_id, interface_name, new_url, results, res_check)
        try:
            preOrderSN(results)
        except Exception as e:
            logger.exception("PATCH Exception %s", e)
    return res


def urlParam(param):
    param1 = param.replace('&quot;', '"')
    return param1


def CredentialId():
    global id
    url = 'http://' + 'api.test.com.cn' + '/api/Security/Authentication/Signin/web'
    body_data = json.dumps({"Identity": 'test', "Password": 'test'})
    headers = {'Connection': 'keep-alive', 'Content-Type': 'application/json'}
    response = requests.post(url=url, data=body_data, headers=headers)
    data = response.text
    regx = '.*"CredentialId":"(.*)","Scene"'
    pm = re.search(regx, data)
    id = pm.group(1)


def seturl(set):
    global setvalue
    sql = "SELECT `setname`,`setvalue` from set_set"
    coon = pymysql.connect(user='root', passwd='root123456!@#$%^', db='autotest', port=3306, host='127.0.0.1',
                           charset='utf8')
    cursor = coon.cursor()
    cur_exec = cursor.execute(sql)
    infos = cursor.fetchmany(cur_exec)
    logger.info("Data in set_set %s", infos)
    coon.commit()
    cursor.close()
    coon.close()
    if infos[0][0] == set:
        setvalue = infos[0][1]
        logger.info("setvalue %s", setvalue)
    return setvalue


def preOrderSN(results):
    global preOrderSN
    regx = '.*"preOrderSN":"(.*)","toHome"'
    pm = re.search(regx, results)
    if pm:
        preOrderSN = pm.group(1).encode('utf-8')
        return preOrderSN
    return False


# 更新apitest_apistep数据库
def writeResult(case_id, response, result):
    if len(response) > 5000:
        response = response[0:5000]
    result = result.encode('utf-8')
    now = time.strftime("%Y-%m-%d %H:%M:%S")
    sql = "UPDATE apitest_apistep set apitest_apistep.apiresponse=%s,apitest_apistep.apistatus=%s,apitest_apistep.update_time=%s where apitest_apistep.id=%s;"
    param = (response, result, now, case_id)
    logger.info("api autotest result is %s", result.decode())
    coon = pymysql.connect(user='root', passwd='root123456!@#$%^', db='autotest', port=3306, host='127.0.0.1',
                           charset='utf8')
    cursor = coon.cursor()
    cursor.execute(sql, param)
    coon.commit()
    cursor.close()
    coon.close()


# 单一接口
def caseWriteResult1(case_id, response, result):
    if len(response) > 5000:
        response = response[0:5000]
    now = time.strftime("%Y-%m-%d %H:%M:%S")
    sql = "UPDATE apitest_apis set apitest_apis.apiresponse=%s,apitest_apis.apistatus=%s,apitest_apis.update_time=%s where apitest_apis.id=%s;"
    param = (response, result, now, case_id)
    logger.info("interfaceTest1  result is %s", response)
    logger.info("interfaceTest1 result is (1-pass, 0-no pass): %s", result)
    coon = pymysql.connect(user='root', passwd='root123456!@#$%^', db='autotest', port=3306, host='127.0.0.1',
                           charset='utf8')
    cursor = coon.cursor()
    cursor.execute(sql, param)
    coon.commit()
    cursor.close()
    coon.close()


# 流程接口
def caseWriteResult(case_id, result):
    now = time.strftime("%Y-%m-%d %H:%M:%S")
    sql = "UPDATE apitest_apitest set apitest_apitest.apitestresult=%s,apitest_apitest.update_time=%s where apitest_apitest.id=%s;"
    param = (result, now, case_id)
    logger.info("interfaceTest result is (1-pass, 0-no pass): %s", result)
    coon = pymysql.connect(user='root', passwd='root123456!@#$%^', db='autotest', port=3306, host='127.0.0.1',
                           charset='utf8')
    cursor = coon.cursor()
    cursor.execute(sql, param)
    coon.commit()
    cursor.close()
    coon.close()


def writeBug(bug_id, interface_name, request, response, res_check):
    interface_name = interface_name.encode('utf-8')
    res_check = res_check.encode('utf-8')
    request = request.encode('utf-8')
    now = time.strftime("%Y-%m-%d %H:%M:%S")
    bugname = str(bug_id) + '_' + interface_name.decode() + '_出错了'
    bugdetail = '[请求数据]<br />' + request.decode() + '<br/>' + '[预期结果]<br/>' + res_check.decode() + '<br/>' + '<br/>' + '[响应数据]<br />' + '<br/>' + response
    logger.info("writeBug bugdetail %s", bugdetail)
    if len(bugdetail) > 2000:
        bugdetail = bugdetail[0:2000]
    coon = pymysql.connect(user='root', passwd='root123456!@#$%^', db='autotest', port=3306, host='127.0.0.1',
                           charset='utf8')
    sql = "INSERT INTO `bug_bug` (" \
          "`bugname`,`bugdetail`,`bugstatus`,`buglevel`, `bugcreater`, `bugassign`,`created_time`,`Product_id`)  " \
          "VALUES ('%s','%s','激活','3','tester', 'tester', '%s', '2');" % (
              bugname, coon.escape_string(bugdetail), now)

    cursor = coon.cursor()
    cursor.execute(sql)
    coon.commit()
    cursor.close()
    coon.close()


def TaskId(results):
    global TaskId
    regx = '.*"TaskId":(.*),"PlanId"'
    pm = re.search(regx, results)
    if pm:
        TaskId = pm.group(1).encode('utf-8')
        logger.info("TaskId %s", TaskId)
        return TaskId
    return False


def taskno(param):
    global taskno
    a = int(time.time())
    taskno = 'task_' + str(a)
    logger.info("taskno %s", taskno)
    return taskno
